﻿using System;
using System.Text;
using GrpcCommon.Models;
using JWT;
using JWT.Algorithms;
using JWT.Exceptions;
using JWT.Serializers;

#pragma warning disable CS0618

namespace GrpcCommon.Helpers
{
    public class JwtHelper
    {
        /// <summary>
        /// 颁发JWT Token
        /// </summary>
        /// <param name="securityKey"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static string GenerateJwt(string securityKey, string userName)
        {
            //var securityKey = AppConfigs.SecurityKey;
            var issuer = AppConfigs.Issuer;
            var expire = AppConfigs.Expire;
            var expTime = new DateTimeOffset(DateTime.Now.AddMinutes(expire)).ToUnixTimeSeconds();

            //身份验证信息
            var jwtToken = new JwtToken { userid = userName, exp = expTime, iss = issuer };
            var key = Encoding.UTF8.GetBytes(securityKey);
            IJwtAlgorithm algorithm = new HMACSHA256Algorithm(); //加密方式
            IJsonSerializer serializer = new JsonNetSerializer(); //序列化Json
            IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder(); //base64加解密
            IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder); //JWT编码
            var token = encoder.Encode(jwtToken, key); //生成令牌

            return token;
        }

        /// <summary>
        /// 校验解析Jwt Token
        /// </summary>
        /// <returns></returns>
        public static Tuple<bool, string> ValidateJwt(string token, string secret)
        {
            try
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtAlgorithm alg = new HMACSHA256Algorithm();
                IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder, alg);
                var payLoad = decoder.Decode(token, secret);

                //校验通过，返回解密后的字符串
                return new Tuple<bool, string>(true, payLoad);
            }
            catch (TokenExpiredException expired)
            {
                //token过期
                return new Tuple<bool, string>(false, expired.Message);
            }
            catch (SignatureVerificationException sve)
            {
                //签名无效
                return new Tuple<bool, string>(false, sve.Message);
            }
            catch (Exception err)
            {
                // 解析出错
                Console.WriteLine(err.StackTrace);
                return new Tuple<bool, string>(false, err.Message);
            }
        }
    }
}
